package net.zapasa.modelo.parser.interfaz;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import net.zapasa.modelo.parser.util.Tags;

import org.apache.tika.sax.ToHTMLContentHandler;
import org.broadleafcommerce.core.catalog.domain.CompetitiveProduct;
import org.broadleafcommerce.core.catalog.domain.CompetitiveProductImpl;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

public abstract class AbstractParserProducts extends ToHTMLContentHandler{
	
	// Es la receta a rellenar
	protected List<CompetitiveProduct> productos = new ArrayList<>();
	


	private String contenido="";  // cadena para almacenar el contenido de un tag
	private Tags tags;
	
	// Etiquetas que ser�n analizadas
	protected static Set<String> ENDLINE = tagParaAnalizar("title", "p", "div", "ul", "ol", "a", "li");
	
	// log
	protected final Logger LOG = Logger.getLogger(AbstractParserProducts.class.toString());

	public AbstractParserProducts() {
		tags = new Tags();
	}
	



	/**
	 * Es el metodo que se tiene que heredar para saber si esta etiqueta se agrega a la receta..
	 * @param name Nombre del elemento a evaluar
	 * @param tags Tag sin cerrar que existen actualmente
	 * @param contenido Contenido del tag actual
	 */
	protected abstract void evaluarElemento(String tagActual, Tags tags, String contenido);

	


	/**
	 * Funcion para almacenar las etiquetas que vamos a analizar
	 * @param elements, 
	 * @return
	 */
	protected final static Set<String> tagParaAnalizar(String... elements) {
        return Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(elements)));
    }
	
	/**
	 * Se ejecuta al cerrar un elemento. Tiene un metodo "gancho" para llamar a 'evaluarElemento'. Es una clase abstracta que hay que heredar
	 * y es donde se decide si este elemento se inserta o no en la receta.
	 */
	public final void endElement(String uri, String localName, String name) throws SAXException {
		if (ENDLINE.contains(name)) {
			
			//System.out.println("F: " + name + ". Valor: " + contenido);
			//System.out.println(tags);
			
			evaluarElemento(name, tags, contenido);
			
			tags.removeLastTag();
		}
	}
	

	/**
	 * Funcion que almacena el valor del tag en el objeto "Receta"
	 */
	public final void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
		if (ENDLINE.contains(name)) {

			List<String> atributos = new ArrayList<String>();
			for (int i = 0; atts.getLength() > i; i++) {
				atributos.add(atts.getValue(i));
			}
			
			//System.out.println("I: " + name + ". Atributos: " + atributos.toString());
			tags.addTag(name, atributos);
		}
	}
	
	/**
	 * Lee la variable y lo introduce en el tag.
	 */
	public final void characters(char[] ch, int start, int length) throws SAXException {
		contenido = new String(ch, start, length); 
		contenido = contenido.trim();
		contenido = contenido.replaceAll("[\n\r]","");
		super.characters(ch, start, length);
	}
	
	
	
	
	// Revisar estos metodos por si no sirven...

	public void startPrefixMapping(String prefix, String uri) throws SAXException {
		//System.out.println("star de prefix: " + prefix + " y su datos son, uri: " + uri);
		super.startPrefixMapping(prefix, uri);
	}

	public void endPrefixMapping(String prefix) throws SAXException {
		//System.out.println("fin de prefix: " + prefix);
		super.endPrefixMapping(prefix);
	}

	@Override
	public void processingInstruction(String target, String data) throws SAXException {
		//System.out.println("procesamos : " + target + " data " + data);
		super.processingInstruction(target, data);
	}

	@Override
	public void skippedEntity(String name) throws SAXException {
		//System.out.println("SAltamos la entidad : " + name);
		super.skippedEntity(name);
	}

	@Override
	public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException {
		//System.out.println("unparsedEntityDecl : " + name + " publicId " + publicId + " systemId " + systemId + " notationName " + notationName);
		super.unparsedEntityDecl(name, publicId, systemId, notationName);
	}
	
	public List<CompetitiveProduct> getProductos() {
		return productos;
	}


}
